﻿
function Search() {

    var searchType = new String("Keyword");
    var requiredDisplayFields = 'Title,Description,Write,Size,Path,Rank';

    this.searchText = new String();
    this.contextUri = new String();
    this.displayFields = new String();
    this.execute = execute;
    this.setKeywordQuery = setKeywordQuery;
    this.setFullTextQuery = setFullTextQuery;
    this.startAt = 1;
    this.resultCount = 100;

    function setKeywordQuery() {
        searchType = "Keyword";
    }

    function setFullTextQuery() {
        searchType = "FullText";
    }

    function execute(clientCallback) {
        switch (searchType) {
            case 'Keyword':
                return doKeywordSearch(this.searchText, this.contextUri, this.displayFields, clientCallback, this.startAt, this.resultCount);
                break;
            case 'FullText':
                return doFullTextSearch(this.searchText, this.contextUri, clientCallback, this.startAt, this.resultCount);
            default:
                throw "That type of search is not supported.";
        }        
    }

    function doFullTextSearch(query, url, callback, start, count) {
        proxies.QueryService.url = url;
        var packet = getFullTextQueryPacket(query, start, count);
        proxies.QueryService.Query.func = callback;
        var resultXml = proxies.QueryService.Query(packet);
        return resultXml;
    }

    function doKeywordSearch(keywords, url, dispFields, callback, start, count) {
        proxies.QueryService.url = url;

        var fields = null;
        if (dispFields != null && dispFields.length > 0) {
            fields = getDisplayPropertyElements(dispFields);
        }
        
        var packet = getKeywordQueryPacket(keywords, fields, start, count);
        proxies.QueryService.Query.func = callback;
        var resultXml = proxies.QueryService.Query(packet);
        return resultXml;
    }

    function mergeRequiredAndDisplayFields(dispFields) {
        var fields = new Array();
        fields = requiredDisplayFields.split(',');

        if (dispFields == null
            || dispFields.length == 0) {
            return fields;
        }

        var userFields = new Array();
        userFields = dispFields.split(',');

        var userField = new String();
        var found = new Boolean();
        found = false;
        
        for (i = 0; i < userFields.length; i++) {
            for (j = 0; j < fields.length; j++) {
                userField = userFields[i];
                while (userField.substr(0, 1) == ' ') {
                    userField = userField.substr(1);
                }
                while (userField.substr(userField.length - 1, 1) == ' ') {
                    userField = userField.substr(0, userField.length - 1);
                }
                if (fields[j].toLowerCase() == userFields[i].toLowerCase()) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                fields.push(userField);
            }
        }
        return fields;
    
    }

    function getDisplayPropertyElements(dispFields) {
        var fields = new Array();
        fields = mergeRequiredAndDisplayFields(dispFields);
        var props = new String();

        for (i = 0; i < fields.length; i++) {
            props = props + getPropertyElement(fields[i]);
        }        
        return props;
    }

    function getPropertyElement(name) {
        return '<Property name="' + name + '"/>';
    }

    function getKeywordQueryPacket(keywords, displayFields, start, count) {
        var packet = '<?xml version="1.0" encoding="utf-8" ?>'
            + '<QueryPacket xmlns="urn:Microsoft.Search.Query" Revision="1000">'
            + '	<Query domain="QDomain">'
            + '		<SupportedFormats>'
            + '			<Format>urn:Microsoft.Search.Response.Document.Document</Format>'
            + '		</SupportedFormats>'
            + '		<Context>'
            + '			<QueryText language="en-US" type="STRING">' + keywords + '</QueryText>'
            + '		</Context>'
            + '		<Range>'
            + '			<StartAt>' + start.toString() + '</StartAt>'
            + '			<Count>' + count.toString() + '</Count>'
            + '		</Range>';

        if (displayFields != null && displayFields.length > 0) {
            packet = packet + '<Properties>' + displayFields + '</Properties>';
        }

        packet = packet + '		<EnableStemming>false</EnableStemming>'
            + '		<IncludeRelevantResults>true</IncludeRelevantResults>'
            + '		<SortByProperties>'
            + '			<SortByProperty name="Rank" Direction="Ascending" Order="1"></SortByProperty>'
            + '		</SortByProperties>'
            + '	</Query>'
            + '</QueryPacket>';
        return packet;

    }

    function getFullTextQueryPacket(query, start, count) {
        var packet = '<?xml version="1.0" encoding="utf-8" ?>'
+ '<QueryPacket xmlns="urn:Microsoft.Search.Query" Revision="1000">'
+ '	<Query domain="QDomain">'
+ '		<SupportedFormats>'
+ '			<Format>urn:Microsoft.Search.Response.Document.Document</Format>'
+ '		</SupportedFormats>'
+ '		<Context>'
+ '			<QueryText language="en-US" type="MSSQLFT">' + query + '</QueryText>'
+ '		</Context>'
+ '		<Range>'
+ '			<StartAt>' + start.toString() + '</StartAt>'
+ '			<Count>' + count.toString() + '</Count>'
+ '		</Range>'
+ '		<EnableStemming>false</EnableStemming>'
+ '		<TrimDuplicates>true</TrimDuplicates>'
+ '		<IgnoreAllNoiseQuery>true</IgnoreAllNoiseQuery>'
+ '		<IncludeRelevantResults>true</IncludeRelevantResults>'
+ '	</Query>'
+ '</QueryPacket>';

        return packet;
    }


}